/************************************************
 * Author       :   XXY
 * Blog         :   https://www.cnblogs.com/jzyl
 * Gitee        :   https://gitee.com/xiaobaichong
 * Email        :   1047185209@QQ.com
 * FileName     :   Game.cs
 * CreateData   :   2023/4/29 13:47:06
 * UnityVersion :   2020.3.33f1c2
 * Description  :   Game 一个游戏舞台 可以存放多个场景
************************************************/

using Main;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

namespace Hotfix
{
    /// <summary>
    /// 实体即为容器(个体)
    /// Game 一个游戏舞台 可以存放多个场景。
    /// 但是只有一个场景时激活状态,其他场景将不会播放
    /// </summary>
    internal sealed class Game : Singleton<Game>
    {
        private Game() { }
        /// <summary>
        /// 所有场景
        /// </summary>
        private Dictionary<Type, SceneBase> scenes = new Dictionary<Type, SceneBase>();
        private SceneBase _currentScene;
        /// <summary>
        /// 当前运行的场景
        /// </summary>
        private SceneBase CurrentScene
        {
            get
            {
                return _currentScene;
            }
            set
            {
                if (_currentScene != value)
                {
                    // 通知场景销毁
                    _currentScene?.OnDisable();
                    _currentScene?.OnDestroy();

                    // 通知场景初始化
                    _currentScene = value;
                    _currentScene?.OnInit();
                    _currentScene?.Awake();
                    _currentScene?.OnEnable();
                    _currentScene?.Start();
                }
            }
        }
        #region 属性
        /// <summary>
        /// (导演)用于驱动整个热更代码逻辑的主游戏对象.
        /// </summary>
        public GameObject director { get; private set; }
        /// <summary>
        /// (导演) 节点对象上的组件
        /// </summary>
        public ComponentIDE componentIDE { get; private set; }
        #endregion

        /// <summary>
        /// 获取当前活动场景
        /// </summary>
        public SceneBase GetActiveScene
        {
            get
            {
                return CurrentScene;
            }
        }
        /// <summary>
        /// 加载Game内的场景
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void LoadScene<T>() where T : SceneBase
        {
            Type type = typeof(T);
            CurrentScene = GetScene<T>();
        }
        /// <summary>
        /// 卸载当前运行的场景，场景被销毁
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns>是否移除当前正在运行的场景</returns>
        public bool UnLoadScene<T>() where T : SceneBase
        {
            Type type = typeof(T);
            if (type == _currentScene?.GetType())
            {
                CurrentScene = null;
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 获取场景
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetScene<T>() where T : SceneBase
        {
            Type type = typeof(T);
            if (scenes.ContainsKey(type))
            {
                return (T)scenes[type];
            }
            else
            {
                LogUtillity.Error($"当前游戏内没有{type}场景");
                return null;
            }
        }
        /// <summary>
        /// 创建一个场景
        /// </summary>
        /// <param name="name"></param>
        /// <returns>是否成功创建场景</returns>
        public bool CreateScene<T>() where T : SceneBase, new()
        {
            Type type = typeof(T);
            if (scenes.ContainsKey(type))
            {
                return false;
            }
            else
            {
                scenes.Add(type, new T());
                return true;
            }
        }
        /// <summary>
        /// 清除游戏内的场景
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void DeleteScene<T>() where T : SceneBase
        {
            Type type = typeof(T);
            if (scenes.ContainsKey(type))
            {
                if (type == _currentScene?.GetType())
                {
                    CurrentScene = null;
                }
                scenes.Remove(type);
            }
        }
        /// <summary>
        /// Game是否包含这个场景
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public bool HasScene<T>()
        {
            Type type = typeof(T);
            return scenes.ContainsKey(type);
        }
    }
}